<?php
declare (strict_types=1);

namespace app\oauth\service;

use think\facade\Cache;
use app\oauth\model\Admin;

class TokenService
{
    private function getKey($user_id)
    {
        return "token_" . $user_id;
    }

    private function getHeaderToken($user_id, $token)
    {
        return $token . "_" . $user_id;
    }

    public static function createHeaderToken($user_id)
    {
        return base64_encode(md5(rand(1000, 9999) . time())) . "_" . $user_id;
    }

    public function updateToken($user_id)
    {
        $header_token = self::createHeaderToken($user_id);
        $return = Admin::update(['token' => $header_token], ['id' => $user_id]);
        if (!$return) {
            throw new \Exception("TokenService updateToken error");
        }

        Cache::delete($this->getKey($user_id));

        return $header_token;
    }

    public function getAdminByToken($user_id, $token)
    {
        if (Cache::get($this->getKey($user_id))) {
            return Cache::get($this->getKey($user_id));
        }

        $admin = Admin::where([
            'token' => $this->getHeaderToken($user_id,$token),
            'id'    => $user_id
        ])->find();

        if (!$admin) {
            return false;
        }

        Cache::set($this->getKey($user_id), $admin);

        return $admin;
    }

    public function delToken($user_id)
    {
        $return = Admin::update(['token' => ''], ['id' => $user_id]);
        if (!$return) {
            throw new \Exception("TokenService delToken error");
        }

        return Cache::delete($this->getKey($user_id));
    }

    public function setLastOperationTime()
    {
        $redis = RedisService::getRedis();
        $key = 'admin:' . AuthService::userId();
        $redis->hSet($key, 'last_operation_time', time());
    }

    public function checkVaildTime()
    {
        $redis = RedisService::getRedis();
        $key = 'admin:' . AuthService::userId();
        $last_operation_time = $redis->hGet($key, 'last_operation_time');

        if ($last_operation_time && time() - $last_operation_time > 86400 * 7) {
            $this->delToken(AuthService::userId());
            $redis->hDel($key, 'last_operation_time');
            return false;
        }

        $this->setLastOperationTime();

        return true;
    }
}